PackerでChef適用済みAMIをサクッと作成する(chef-solo provisionerの活用)
ども、大瀧です。Amazon EC2のテンプレートであるAMI(Amazon Machine Image)の作成が設定ファイルとコマンドラインで簡単にできる、Packerというツールを以前ご紹介しました。
その記事の後半で触れていたchef-solo provisioner(Chef連携機能)が、3日前にようやくmasterにマージされたので試してみました。
chef-solo provisionerとは
Packerは、AWS環境だとEC2インスタンスを作成し(下図1)、設定ファイル(Template)を元に一定の構成を行い(下図2)、そこから新たなAMIを作成できます(下図3)。
chef-solo provisionerは、下図2のEC2インスタンスの構成としてChefのインストールとchef-soloによるcookbooks/recipeを実行する機能を持ちます。Packerおよびchef-solo provisionerは、ChefでEC2を管理するときの従来の懸念事項だった以下が解消できる画期的ソリューションになります!
- Chefの1回目の実行が遅い(ソフトウェアのインストール/ビルドが行われるため)
- あらかじめChefを1回実行したAMIを作ると、AMIの管理が煩雑になる(AMIは1つに統一したい、AMIのバージョンアップに追随したい)
1. ソースからPackerをビルドする
ビルド済みパッケージがリリースされました(バージョン0.3.5)!ダウンロードページからダウンロードし、通常のセットアップで導入できるようになりました。以下のビルド作業は不要です。
本日(2013/08/26)時点では、ビルド済みのリリースパッケージにはまだ含まれていないため、githubのソースから自分でビルドする必要があります。Packerのビルド手順はREADMEのDeveloping Packerを参照してください。GoとMercurialを事前にインストールしておく必要があります。
$ packer -v Packer v0.3.5.dev (99dd3ccec5cf84659fced53f5c7b6a304263e03f) $
2. Cookbookの準備
適用するChefのCookbookを準備します。といっても、Packer向けの特別な設定は必要ありません。今回はBerkshelfでnginxのCommunity Cookbookを用意しました。
$ ls cookbooks/nginx/ Berksfile Gemfile.lock TESTING.md definitions/ metadata.rb CHANGELOG.md LICENSE attributes/ files/ recipes/ CONTRIBUTING.md README.md chefignore metadata.json templates/ $ cat cookbooks/nginx/README.md | head -n 20 Description =========== Installs nginx from package OR source code and sets up configuration handling similar to Debian's Apache2 scripts. (略) $
3. Templateの作成
では、chef-soloをProvisinerとして実行するためのPackerのTemplateを以下のように作成します。今回は、Amazon Linux 2013.03 64bit公式AMI(ami-39b23d38)を使用します。
packer.json
{ "builders": [{ "type": "amazon-ebs", "access_key": "XXXXXXXXXXXXXXXX", "secret_key": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "region": "ap-northeast-1", "source_ami": "ami-39b23d38", "instance_type": "t1.micro", "ssh_username": "ec2-user", "ssh_timeout": "5m", "ami_name": "packer-example {{timestamp}}" }], "provisioners": [{ "type": "chef-solo", "cookbooks_paths": ["./cookbooks"], "recipes": ["nginx"], "json": {}, "prevent_sudo": false, "skip_install": false }] }
以下補足です。
- 11行目の{{timestamp}}は、前回の記事で{{.CreateTime}}と記述していた箇所です。書き方が変わりました。
- 14行目のtypeアトリビュートにchef-soloと記述し、chef-soloの設定を続けていきます。まだドキュメント化されていない部分なので、なんとなく読み取ってください(苦笑)。
4. Packerの実行
Templateができたら、いよいよPackerを実行します。EC2インスタンスの作成ログからchef-soloの実行結果、AMIの作成ログまで順に出力されていきます。
$ packer build packer.json amazon-ebs output will be in this color. ==> amazon-ebs: Creating temporary keypair for this instance... ==> amazon-ebs: Creating temporary security group for this instance... ==> amazon-ebs: Authorizing SSH access on the temporary security group... ==> amazon-ebs: Launching a source AWS instance... ==> amazon-ebs: Waiting for instance (i-XXXXXXXX) to become ready... ==> amazon-ebs: Waiting for SSH to become available... ==> amazon-ebs: Connected to SSH! ==> amazon-ebs: Installing Chef Solo amazon-ebs: % Total % Received % Xferd Average Speed Time Time Time Current amazon-ebs: Dload Upload Total Spent Left Speed 100 6790 100 6790 0 0 6980 0 --:--:-- --:--:-- --:--:-- 8864--:--:-- 0 amazon-ebs: Downloading Chef for el... amazon-ebs: Installing Chef amazon-ebs: warning: /tmp/tmp.IoOUBQU5/chef-.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 83ef826a: NOKEY amazon-ebs: Preparing... ########################################### [100%] amazon-ebs: 1:chef ########################################### [100%] amazon-ebs: Thank you for installing Chef! ==> amazon-ebs: Creating Chef configuration file... ==> amazon-ebs: Creating and uploading Chef attributes file ==> amazon-ebs: Copying cookbook path: ./cookbooks ==> amazon-ebs: Beginning Chef Solo run amazon-ebs: Starting Chef Client, version 11.6.0 amazon-ebs: Compiling Cookbooks... amazon-ebs: Recipe: ohai::default amazon-ebs: * remote_directory[/etc/chef/ohai_plugins] action create amazon-ebs: - create new directory /etc/chef/ohai_plugins amazon-ebs: - change mode from '' to '0755'Recipe: <Dynamically Defined Resource> amazon-ebs: * cookbook_file[/etc/chef/ohai_plugins/README] action create amazon-ebs: - create new file /etc/chef/ohai_plugins/README amazon-ebs: - update content in file /etc/chef/ohai_plugins/README from none to 775fa7 amazon-ebs: --- /etc/chef/ohai_plugins/README 2013-08-26 08:03:22.915209544 +0000 amazon-ebs: +++ /tmp/.README20130826-3857-14m7zaz 2013-08-26 08:03:22.915209544 +0000 amazon-ebs: @@ -0,0 +1 @@ amazon-ebs: +This directory contains custom plugins for Ohai. amazon-ebs: - change mode from '' to '0644' amazon-ebs: amazon-ebs: Recipe: ohai::default amazon-ebs: * ohai[custom_plugins] action reload amazon-ebs: - re-run ohai and merge results into node attributes amazon-ebs: [2013-08-26T08:03:23+00:00] WARN: Cloning resource attributes for service[nginx] from prior resource (CHEF-3694) amazon-ebs: [2013-08-26T08:03:23+00:00] WARN: Previous service[nginx]: /tmp/provision/chef-solo/cookbooks/cookbooks/nginx/recipes/default.rb:42:in `from_file' amazon-ebs: [2013-08-26T08:03:23+00:00] WARN: Current service[nginx]: /tmp/provision/chef-solo/cookbooks/cookbooks/nginx/recipes/default.rb:49:in `from_file' amazon-ebs: Converging 19 resources amazon-ebs: Recipe: nginx::ohai_plugin amazon-ebs: * ohai[reload_nginx] action nothing (skipped due to action :nothing) amazon-ebs: * template[/etc/chef/ohai_plugins/nginx.rb] action create amazon-ebs: - create new file /etc/chef/ohai_plugins/nginx.rb amazon-ebs: - update content in file /etc/chef/ohai_plugins/nginx.rb from none to a0b829 amazon-ebs: --- /etc/chef/ohai_plugins/nginx.rb 2013-08-26 08:03:23.903209893 +0000 amazon-ebs: +++ /tmp/chef-rendered-template20130826-3857-1jtq9lt 2013-08-26 08:03:23.903209893 +0000 amazon-ebs: @@ -0,0 +1,66 @@ amazon-ebs: +# amazon-ebs: +# Author:: Jamie Winsor (<jamie@vialstudios.com>) amazon-ebs: +# amazon-ebs: +# Copyright 2012, Riot Games amazon-ebs: +# amazon-ebs: +# Licensed under the Apache License, Version 2.0 (the "License"); amazon-ebs: +# you may not use this file except in compliance with the License. amazon-ebs: +# You may obtain a copy of the License at amazon-ebs: +# amazon-ebs: +# http://www.apache.org/licenses/LICENSE-2.0 amazon-ebs: +# amazon-ebs: +# Unless required by applicable law or agreed to in writing, software amazon-ebs: +# distributed under the License is distributed on an "AS IS" BASIS, amazon-ebs: +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. amazon-ebs: +# See the License for the specific language governing permissions and amazon-ebs: +# limitations under the License. amazon-ebs: +# amazon-ebs: + amazon-ebs: +provides "nginx" amazon-ebs: +provides "nginx/version" amazon-ebs: +provides "nginx/configure_arguments" amazon-ebs: +provides "nginx/prefix" amazon-ebs: +provides "nginx/conf_path" amazon-ebs: + amazon-ebs: +def parse_flags(flags) amazon-ebs: + prefix = nil amazon-ebs: + conf_path = nil amazon-ebs: + amazon-ebs: + flags.each do |flag| amazon-ebs: + case flag amazon-ebs: + when /^--prefix=(.+)$/ amazon-ebs: + prefix = $1 amazon-ebs: + when /^--conf-path=(.+)$/ amazon-ebs: + conf_path = $1 amazon-ebs: + end amazon-ebs: + end amazon-ebs: + amazon-ebs: + [ prefix, conf_path ] amazon-ebs: +end amazon-ebs: + amazon-ebs: +nginx Mash.new unless nginx amazon-ebs: +nginx[:version] = nil unless nginx[:version] amazon-ebs: +nginx[:configure_arguments] = Array.new unless nginx[:configure_arguments] amazon-ebs: +nginx[:prefix] = nil unless nginx[:prefix] amazon-ebs: +nginx[:conf_path] = nil unless nginx[:conf_path] amazon-ebs: + amazon-ebs: +status, stdout, stderr = run_command(:no_status_check => true, :cwd => "/opt/nginx-1.2.6", :command => "/usr/sbin/nginx -V") amazon-ebs: + amazon-ebs: +if status == 0 amazon-ebs: + stderr.split("\n").each do |line| amazon-ebs: + case line amazon-ebs: + when /^configure arguments:(.+)/ amazon-ebs: + # This could be better: I'm splitting on configure arguments which removes them and also amazon-ebs: + # adds a blank string at index 0 of the array. This is why we drop index 0 and map to amazon-ebs: + # add the '--' prefix back to the configure argument. amazon-ebs: + nginx[:configure_arguments] = $1.split(/\s--/).drop(1).map { |ca| "--#{ca}" } amazon-ebs: + amazon-ebs: + prefix, conf_path = parse_flags(nginx[:configure_arguments]) amazon-ebs: + amazon-ebs: + nginx[:prefix] = prefix amazon-ebs: + nginx[:conf_path] = conf_path amazon-ebs: + when /^nginx version: nginx\/(.+)/ amazon-ebs: + nginx[:version] = $1 amazon-ebs: + end amazon-ebs: + end amazon-ebs: +end amazon-ebs: - change mode from '' to '0755' amazon-ebs: - change owner from '' to 'root' amazon-ebs: - change group from '' to 'root' amazon-ebs: * ohai[reload_nginx] action reload amazon-ebs: - re-run ohai and merge results into node attributes amazon-ebs: Recipe: ohai::default amazon-ebs: * remote_directory[/etc/chef/ohai_plugins] action nothing (skipped due to action :nothing) amazon-ebs: * ohai[custom_plugins] action nothing (skipped due to action :nothing) amazon-ebs: Recipe: yum::epel amazon-ebs: * yum_key[RPM-GPG-KEY-EPEL-6] action add (up to date) amazon-ebs: * yum_repository[epel] action add (up to date) amazon-ebs: * yum_repository[epel] action update[2013-08-26T08:03:24+00:00] WARN: Cloning resource attributes for yum_key[RPM-GPG-KEY-EPEL-6] from prior resource (CHEF-3694) amazon-ebs: [2013-08-26T08:03:24+00:00] WARN: Previous yum_key[RPM-GPG-KEY-EPEL-6]: /tmp/provision/chef-solo/cookbooks/cookbooks/yum/recipes/epel.rb:22:in `from_file' amazon-ebs: [2013-08-26T08:03:24+00:00] WARN: Current yum_key[RPM-GPG-KEY-EPEL-6]: /tmp/provision/chef-solo/cookbooks/cookbooks/yum/providers/repository.rb:85:in `repo_config' amazon-ebs: (up to date) amazon-ebs: Recipe: <Dynamically Defined Resource> amazon-ebs: * yum_key[RPM-GPG-KEY-EPEL-6] action add (up to date) amazon-ebs: * execute[yum-makecache] action nothing (skipped due to action :nothing) amazon-ebs: * ruby_block[reload-internal-yum-cache] action nothing (skipped due to action :nothing) amazon-ebs: * template[/etc/yum.repos.d/epel.repo] action create amazon-ebs: - update content in file /etc/yum.repos.d/epel.repo from 78d374 to 20221e amazon-ebs: --- /etc/yum.repos.d/epel.repo 2013-03-01 07:52:14.000000000 +0000 amazon-ebs: +++ /tmp/chef-rendered-template20130826-3857-4u8iz9 2013-08-26 08:03:24.071209953 +0000 amazon-ebs: @@ -1,26 +1,8 @@ amazon-ebs: +# Generated by Chef for ip-172-31-19-207.ap-northeast-1.compute.internal amazon-ebs: +# Local modifications will be overwritten. amazon-ebs: [epel] amazon-ebs: -name=Extra Packages for Enterprise Linux 6 - $basearch amazon-ebs: -#baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch amazon-ebs: -mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch amazon-ebs: -failovermethod=priority amazon-ebs: -enabled=0 amazon-ebs: +name=Extra Packages for Enterprise Linux amazon-ebs: +mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=epel-6&arch=$basearch amazon-ebs: gpgcheck=1 amazon-ebs: gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 amazon-ebs: - amazon-ebs: -[epel-debuginfo] amazon-ebs: -name=Extra Packages for Enterprise Linux 6 - $basearch - Debug amazon-ebs: -#baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch/debug amazon-ebs: -mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-6&arch=$basearch amazon-ebs: -failovermethod=priority amazon-ebs: -enabled=0 amazon-ebs: -gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 amazon-ebs: -gpgcheck=1 amazon-ebs: - amazon-ebs: -[epel-source] amazon-ebs: -name=Extra Packages for Enterprise Linux 6 - $basearch - Source amazon-ebs: -#baseurl=http://download.fedoraproject.org/pub/epel/6/SRPMS amazon-ebs: -mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-source-6&arch=$basearch amazon-ebs: -failovermethod=priority amazon-ebs: -enabled=0 amazon-ebs: -gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 amazon-ebs: -gpgcheck=1 amazon-ebs: +enabled=1 amazon-ebs: * execute[yum-makecache] action run amazon-ebs: - execute yum -q makecache amazon-ebs: * ruby_block[reload-internal-yum-cache] action create amazon-ebs: - execute the ruby block reload-internal-yum-cache amazon-ebs: Recipe: nginx::default amazon-ebs: * package[nginx] action install amazon-ebs: - install version 1.2.9-1.11.amzn1 of package nginx amazon-ebs: * service[nginx] action enable amazon-ebs: - enable service service[nginx] amazon-ebs: Recipe: nginx::commons_dir amazon-ebs: * directory[/etc/nginx] action create (up to date) amazon-ebs: * directory[/var/log/nginx] action create amazon-ebs: - change mode from '0700' to '0755' amazon-ebs: * directory[/etc/nginx/sites-available] action create amazon-ebs: - create new directory /etc/nginx/sites-available amazon-ebs: - change mode from '' to '0755' amazon-ebs: - change owner from '' to 'root' amazon-ebs: - change group from '' to 'root' amazon-ebs: * directory[/etc/nginx/sites-enabled] action create amazon-ebs: - create new directory /etc/nginx/sites-enabled amazon-ebs: - change mode from '' to '0755' amazon-ebs: - change owner from '' to 'root' amazon-ebs: - change group from '' to 'root' amazon-ebs: * directory[/etc/nginx/conf.d] action create (up to date) amazon-ebs: Recipe: nginx::commons_script amazon-ebs: * template[/usr/sbin/nxensite] action create amazon-ebs: - create new file /usr/sbin/nxensite amazon-ebs: - update content in file /usr/sbin/nxensite from none to fa46fb amazon-ebs: --- /usr/sbin/nxensite 2013-08-26 08:03:46.811217642 +0000 amazon-ebs: +++ /tmp/chef-rendered-template20130826-3857-1ypsv7g 2013-08-26 08:03:46.819217644 +0000 amazon-ebs: @@ -0,0 +1,38 @@ amazon-ebs: +#!/bin/sh -e amazon-ebs: + amazon-ebs: +SYSCONFDIR='/etc/nginx' amazon-ebs: + amazon-ebs: +if [ -z $1 ]; then amazon-ebs: + echo "Which site would you like to enable?" amazon-ebs: + echo -n "Your choices are: " amazon-ebs: + ls $SYSCONFDIR/sites-available/* | \ amazon-ebs: + sed -e "s,$SYSCONFDIR/sites-available/,,g" | xargs echo amazon-ebs: + echo -n "Site name? " amazon-ebs: + read SITENAME amazon-ebs: +else amazon-ebs: + SITENAME=$1 amazon-ebs: +fi amazon-ebs: + amazon-ebs: +if [ $SITENAME = "default" ]; then amazon-ebs: + PRIORITY="000" amazon-ebs: +fi amazon-ebs: + amazon-ebs: +if [ -e $SYSCONFDIR/sites-enabled/$SITENAME -o \ amazon-ebs: + -e $SYSCONFDIR/sites-enabled/"$PRIORITY"-"$SITENAME" ]; then amazon-ebs: + echo "This site is already enabled!" amazon-ebs: + exit 0 amazon-ebs: +fi amazon-ebs: + amazon-ebs: +if ! [ -e $SYSCONFDIR/sites-available/$SITENAME ]; then amazon-ebs: + echo "This site does not exist!" amazon-ebs: + exit 1 amazon-ebs: +fi amazon-ebs: + amazon-ebs: +if [ $SITENAME = "default" ]; then amazon-ebs: + ln -sf $SYSCONFDIR/sites-available/$SITENAME \ amazon-ebs: + $SYSCONFDIR/sites-enabled/"$PRIORITY"-"$SITENAME" amazon-ebs: +else amazon-ebs: + ln -sf $SYSCONFDIR/sites-available/$SITENAME $SYSCONFDIR/sites-enabled/$SITENAME amazon-ebs: +fi amazon-ebs: + amazon-ebs: +echo "Site $SITENAME installed; reload nginx to enable." amazon-ebs: - change mode from '' to '0755' amazon-ebs: - change owner from '' to 'root' amazon-ebs: - change group from '' to 'root' amazon-ebs: * template[/usr/sbin/nxdissite] action create amazon-ebs: - create new file /usr/sbin/nxdissite amazon-ebs: - update content in file /usr/sbin/nxdissite from none to cc16ec amazon-ebs: --- /usr/sbin/nxdissite 2013-08-26 08:03:46.931217683 +0000 amazon-ebs: +++ /tmp/chef-rendered-template20130826-3857-4g2h72 2013-08-26 08:03:46.931217683 +0000 amazon-ebs: @@ -0,0 +1,29 @@ amazon-ebs: +#!/bin/sh -e amazon-ebs: + amazon-ebs: +SYSCONFDIR='/etc/nginx' amazon-ebs: + amazon-ebs: +if [ -z $1 ]; then amazon-ebs: + echo "Which site would you like to disable?" amazon-ebs: + echo -n "Your choices are: " amazon-ebs: + ls $SYSCONFDIR/sites-enabled/* | \ amazon-ebs: + sed -e "s,$SYSCONFDIR/sites-enabled/,,g" | xargs echo amazon-ebs: + echo -n "Site name? " amazon-ebs: + read SITENAME amazon-ebs: +else amazon-ebs: + SITENAME=$1 amazon-ebs: +fi amazon-ebs: + amazon-ebs: +if [ $SITENAME = "default" ]; then amazon-ebs: + PRIORITY="000" amazon-ebs: +fi amazon-ebs: + amazon-ebs: +if ! [ -e $SYSCONFDIR/sites-enabled/$SITENAME -o \ amazon-ebs: + -e $SYSCONFDIR/sites-enabled/"$PRIORITY"-"$SITENAME" ]; then amazon-ebs: + echo "This site is already disabled, or does not exist!" amazon-ebs: + exit 1 amazon-ebs: +fi amazon-ebs: + amazon-ebs: +if ! rm $SYSCONFDIR/sites-enabled/$SITENAME 2>/dev/null; then amazon-ebs: + rm -f $SYSCONFDIR/sites-enabled/"$PRIORITY"-"$SITENAME" amazon-ebs: +fi amazon-ebs: +echo "Site $SITENAME disabled; reload nginx to disable." amazon-ebs: - change mode from '' to '0755' amazon-ebs: - change owner from '' to 'root' amazon-ebs: - change group from '' to 'root' amazon-ebs: Recipe: nginx::commons_conf amazon-ebs: * template[nginx.conf] action create amazon-ebs: - update content in file /etc/nginx/nginx.conf from a256fc to d19745 amazon-ebs: --- /etc/nginx/nginx.conf 2013-05-14 18:25:23.000000000 +0000 amazon-ebs: +++ /tmp/chef-rendered-template20130826-3857-1rwtxfz 2013-08-26 08:03:47.043217718 +0000 amazon-ebs: @@ -1,131 +1,39 @@ amazon-ebs: -# For more information on configuration, see: amazon-ebs: -# * Official English Documentation: http://nginx.org/en/docs/ amazon-ebs: -# * Official Russian Documentation: http://nginx.org/ru/docs/ amazon-ebs: - amazon-ebs: -user nginx; amazon-ebs: +user nginx; amazon-ebs: worker_processes 1; amazon-ebs: amazon-ebs: error_log /var/log/nginx/error.log; amazon-ebs: -#error_log /var/log/nginx/error.log notice; amazon-ebs: -#error_log /var/log/nginx/error.log info; amazon-ebs: - amazon-ebs: pid /var/run/nginx.pid; amazon-ebs: amazon-ebs: - amazon-ebs: events { amazon-ebs: - worker_connections 1024; amazon-ebs: + worker_connections 1024; amazon-ebs: } amazon-ebs: amazon-ebs: - amazon-ebs: http { amazon-ebs: - include /etc/nginx/mime.types; amazon-ebs: - default_type application/octet-stream; amazon-ebs: amazon-ebs: - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' amazon-ebs: - '$status $body_bytes_sent "$http_referer" ' amazon-ebs: - '"$http_user_agent" "$http_x_forwarded_for"'; amazon-ebs: - amazon-ebs: - access_log /var/log/nginx/access.log main; amazon-ebs: - amazon-ebs: - sendfile on; amazon-ebs: - #tcp_nopush on; amazon-ebs: - amazon-ebs: - #keepalive_timeout 0; amazon-ebs: - keepalive_timeout 65; amazon-ebs: - amazon-ebs: - #gzip on; amazon-ebs: - amazon-ebs: - # Load modular configuration files from the /etc/nginx/conf.d directory. amazon-ebs: - # See http://nginx.org/en/docs/ngx_core_module.html#include amazon-ebs: - # for more information. amazon-ebs: - include /etc/nginx/conf.d/*.conf; amazon-ebs: - amazon-ebs: - server { amazon-ebs: - listen 80; amazon-ebs: - server_name localhost; amazon-ebs: - amazon-ebs: - #charset koi8-r; amazon-ebs: - amazon-ebs: - #access_log /var/log/nginx/host.access.log main; amazon-ebs: - amazon-ebs: - location / { amazon-ebs: - root /usr/share/nginx/html; amazon-ebs: - index index.html index.htm; amazon-ebs: - } amazon-ebs: - amazon-ebs: - # redirect server error pages to the static page /40x.html amazon-ebs: - # amazon-ebs: - error_page 404 /404.html; amazon-ebs: - location = /40x.html { amazon-ebs: - root /usr/share/nginx/html; amazon-ebs: - } amazon-ebs: - amazon-ebs: - # redirect server error pages to the static page /50x.html amazon-ebs: - # amazon-ebs: - error_page 500 502 503 504 /50x.html; amazon-ebs: - location = /50x.html { amazon-ebs: - root /usr/share/nginx/html; amazon-ebs: - } amazon-ebs: - amazon-ebs: - # proxy the PHP scripts to Apache listening on 127.0.0.1:80 amazon-ebs: - # amazon-ebs: - #location ~ \.php$ { amazon-ebs: - # proxy_pass http://127.0.0.1; amazon-ebs: - #} amazon-ebs: - amazon-ebs: - # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 amazon-ebs: - # amazon-ebs: - #location ~ \.php$ { amazon-ebs: - # root html; amazon-ebs: - # fastcgi_pass 127.0.0.1:9000; amazon-ebs: - # fastcgi_index index.php; amazon-ebs: - # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; amazon-ebs: - # include fastcgi_params; amazon-ebs: - #} amazon-ebs: - amazon-ebs: - # deny access to .htaccess files, if Apache's document root amazon-ebs: - # concurs with nginx's one amazon-ebs: - # amazon-ebs: - #location ~ /\.ht { amazon-ebs: - # deny all; amazon-ebs: - #} amazon-ebs: - } amazon-ebs: - amazon-ebs: - amazon-ebs: - # another virtual host using mix of IP-, name-, and port-based configuration amazon-ebs: - # amazon-ebs: - #server { amazon-ebs: - # listen 8000; amazon-ebs: - # listen somename:8080; amazon-ebs: - # server_name somename alias another.alias; amazon-ebs: - amazon-ebs: - # location / { amazon-ebs: - # root html; amazon-ebs: - # index index.html index.htm; amazon-ebs: - # } amazon-ebs: - #} amazon-ebs: - amazon-ebs: - amazon-ebs: - # HTTPS server amazon-ebs: - # amazon-ebs: - #server { amazon-ebs: - # listen 443; amazon-ebs: - # server_name localhost; amazon-ebs: - amazon-ebs: - # ssl on; amazon-ebs: - # ssl_certificate cert.pem; amazon-ebs: - # ssl_certificate_key cert.key; amazon-ebs: - amazon-ebs: - # ssl_session_timeout 5m; amazon-ebs: - amazon-ebs: - # ssl_protocols SSLv2 SSLv3 TLSv1; amazon-ebs: - # ssl_ciphers HIGH:!aNULL:!MD5; amazon-ebs: - # ssl_prefer_server_ciphers on; amazon-ebs: - amazon-ebs: - # location / { amazon-ebs: - # root html; amazon-ebs: - # index index.html index.htm; amazon-ebs: - # } amazon-ebs: - #} amazon-ebs: + include /etc/nginx/mime.types; amazon-ebs: + default_type application/octet-stream; amazon-ebs: + amazon-ebs: + access_log /var/log/nginx/access.log; amazon-ebs: + amazon-ebs: + sendfile on; amazon-ebs: + tcp_nopush on; amazon-ebs: + tcp_nodelay on; amazon-ebs: + amazon-ebs: + keepalive_timeout 65; amazon-ebs: + amazon-ebs: + gzip on; amazon-ebs: + gzip_http_version 1.0; amazon-ebs: + gzip_comp_level 2; amazon-ebs: + gzip_proxied any; amazon-ebs: + gzip_vary off; amazon-ebs: + gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript application/json; amazon-ebs: + gzip_min_length 1000; amazon-ebs: + gzip_disable "MSIE [1-6]\."; amazon-ebs: + amazon-ebs: + server_names_hash_bucket_size 64; amazon-ebs: + types_hash_max_size 2048; amazon-ebs: + types_hash_bucket_size 64; amazon-ebs: amazon-ebs: + include /etc/nginx/conf.d/*.conf; amazon-ebs: + include /etc/nginx/sites-enabled/*; amazon-ebs: } amazon-ebs: * template[/etc/nginx/sites-available/default] action create amazon-ebs: - create new file /etc/nginx/sites-available/default amazon-ebs: - update content in file /etc/nginx/sites-available/default from none to 113c3d amazon-ebs: --- /etc/nginx/sites-available/default 2013-08-26 08:03:47.415217839 +0000 amazon-ebs: +++ /tmp/chef-rendered-template20130826-3857-nmxp26 2013-08-26 08:03:47.415217839 +0000 amazon-ebs: @@ -0,0 +1,11 @@ amazon-ebs: +server { amazon-ebs: + listen 80; amazon-ebs: + server_name ip-XX-XX-XX-XX; amazon-ebs: + amazon-ebs: + access_log /var/log/nginx/localhost.access.log; amazon-ebs: + amazon-ebs: + location / { amazon-ebs: + root /var/www/nginx-default; amazon-ebs: + index index.html index.htm; amazon-ebs: + } amazon-ebs: +} amazon-ebs: - change mode from '' to '0644' amazon-ebs: - change owner from '' to 'root' amazon-ebs: - change group from '' to 'root' amazon-ebs: * execute[nxensite default] action run amazon-ebs: - execute /usr/sbin/nxensite default amazon-ebs: Recipe: nginx::default amazon-ebs: * service[nginx] action start amazon-ebs: - start service service[nginx] amazon-ebs: * service[nginx] action reload amazon-ebs: - reload service service[nginx] amazon-ebs: Chef Client finished, 20 resources updated ==> amazon-ebs: Stopping the source instance... ==> amazon-ebs: Waiting for the instance to stop... ==> amazon-ebs: Creating the AMI: packer-example 1377504007 ==> amazon-ebs: AMI: ami-XXXXXXXX ==> amazon-ebs: Waiting for AMI to become ready... ==> amazon-ebs: Terminating the source AWS instance... ==> amazon-ebs: Deleting temporary security group... ==> amazon-ebs: Deleting temporary keypair... Build 'amazon-ebs' finished. ==> Builds finished. The artifacts of successful builds are: --> amazon-ebs: AMIs were created: ap-northeast-1: ami-XXXXXXXX
作成されたAMIを元にEC2インスタンスを起動し、SSHで接続してみます。
$ ssh ec2-user@ec2-XX-XX-XX-XX.ap-northeast-1.compute.amazonaws.com [ec2-user@ip-XX-XX-XX-XX ~]$ rpm -q nginx nginx-1.2.9-1.11.amzn1.x86_64 [ec2-user@ip-XX-XX-XX-XX ~]$ rpm -q chef chef-11.6.0-1.el6.x86_64 [ec2-user@ip-XX-XX-XX-XX ~]$
nginxとchefがちゃんとインストールされていますね!!
まとめ
というわけで、Packerで簡単にChefのインストール&実行したAMIを作成できることをご紹介しました。
Packerの開発は相変わらず非常に活発で、chroot環境のEC2で並列実行するBuilderというユニークな仕組みも追加されています。こちらも試して、またブログで紹介したいです。
皆さんもPackerを活用して楽にAMIを管理しましょう!!